package com.wuwei.elearning.utils;

import com.wuwei.elearning.question.domain.ChangedLog;
import com.wuwei.elearning.question.domain.Question;
import com.wuwei.elearning.question.domain.QuestionTranslated;
import com.wuwei.elearning.question.mapper.ChangedLogMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@Component
@Slf4j
public class RecordUtils {

    @Resource
    private ChangedLogMapper changedLogMapper;

    /**
     * 比较两个 Question 对象，并记录所有差异到日志中。
     *
     * @param oldQuestion 原始的 Question 对象 (变更前)。
     * @param newQuestion 更新后的 Question 对象 (变更后)。
     */
    public  void recordQuestionChange(Question oldQuestion, Question newQuestion,Long account) {
        if (oldQuestion == null || newQuestion == null) {
            log.warn("无法记录题目变更，传入的某个对象为空。");
            return;
        }

        List<String> changes = new ArrayList<>();
        Long id = oldQuestion.getId(); // 假设ID不会改变

        // 比较每个字段，并将变更描述添加到列表中
        appendChange(account,changes, "题目内容", oldQuestion.getQuestion(), newQuestion.getQuestion());
        appendChange(account,changes, "选项A", oldQuestion.getItem1(), newQuestion.getItem1());
        appendChange(account,changes, "选项B", oldQuestion.getItem2(), newQuestion.getItem2());
        appendChange(account,changes, "选项C", oldQuestion.getItem3(), newQuestion.getItem3());
        appendChange(account,changes, "选项D", oldQuestion.getItem4(), newQuestion.getItem4());
        appendChange(account,changes, "答案", oldQuestion.getAnswer(), newQuestion.getAnswer());
        appendChange(account,changes, "解析", oldQuestion.getRemark(), newQuestion.getRemark());
        appendChange(account,changes, "课程ID", oldQuestion.getSubjectId(), newQuestion.getSubjectId());
        appendChange(account,changes, "特别关注点ID", oldQuestion.getSpecialCareId(), newQuestion.getSpecialCareId());

        // 仅在有实际变更时才记录日志
        if (!changes.isEmpty()) {
            String desc = "题目变更记录:对应题目ID:"+id+"。";
            log.info(desc);
            ChangedLog changedLog = new ChangedLog();
            changedLog.setCreatedTime(LocalDateTime.now());
            changedLog.setCreatedBy(account);
            changedLog.setDescription(desc+"\n"+String.join("\n", changes));
            changedLogMapper.insert(changedLog);
            changes.forEach(log::info);
        }
    }

    /**
     * 比较两个 QuestionTranslated 对象，并记录所有差异到日志中。
     *
     * @param oldTrans 原始的 QuestionTranslated 对象 (变更前)。
     * @param newTrans 更新后的 QuestionTranslated 对象 (变更后)。
     */
    public  void recordQuestionTranslatedChange(QuestionTranslated oldTrans, QuestionTranslated newTrans,Long account) {
        if (oldTrans == null || newTrans == null) {
            log.warn("无法记录英语题目变更，传入的某个对象为空。");
            return;
        }

        List<String> changes = new ArrayList<>();
        Long questionId = oldTrans.getQuestionId(); // 使用外键questionId作为日志上下文

        // 比较每个字段
        appendChange(account,changes, "题目内容(英语)", oldTrans.getQuestion(), newTrans.getQuestion());
        appendChange(account,changes, "选项A(英语)", oldTrans.getItem1(), newTrans.getItem1());
        appendChange(account,changes, "选项B(英语)", oldTrans.getItem2(), newTrans.getItem2());
        appendChange(account,changes, "选项C(英语)", oldTrans.getItem3(), newTrans.getItem3());
        appendChange(account,changes, "选项D(英语)", oldTrans.getItem4(), newTrans.getItem4());
        appendChange(account,changes, "答案(英语)", oldTrans.getAnswer(), newTrans.getAnswer());
        appendChange(account,changes, "解析(英语)", oldTrans.getRemark(), newTrans.getRemark());

        if (!changes.isEmpty()) {
            String desc = "英语题目变更记录:对应题目questionId:"+questionId+"。";
            log.info(desc);
            ChangedLog changedLog = new ChangedLog();
            changedLog.setCreatedTime(LocalDateTime.now());
            changedLog.setCreatedBy(account);
            changedLog.setDescription(desc+"\n"+String.join("\n", changes));
            changedLogMapper.insert(changedLog);
            changes.forEach(log::info);
        }
    }

    /**
     * 一个辅助方法，用于比较两个值并将格式化的变更信息添加到列表中。
     * 此方法能正确处理null值，并且在两个值相同时不会添加任何信息。
     *
     * @param changes   用于存储变更描述的列表。
     * @param fieldName 正在比较的字段的中文名称。
     * @param oldValue  字段的原始值。
     * @param newValue  字段的新值。
     */
    private static void appendChange(Long account,List<String> changes, String fieldName, Object oldValue, Object newValue) {
        // 使用 Objects.equals 进行 null 安全的比较
        if (!Objects.equals(oldValue, newValue)) {
            changes.add(String.format("账号"+account+"将字段 '%s' 由 [%s] 修改为 [%s]。", fieldName, oldValue, newValue));
        }
    }
}
